package controller

import (
	"net/http"
	"strconv"

	"github.com/example/video_backend/internal/model"
	"github.com/example/video_backend/internal/service"
	"github.com/example/video_backend/pkg/logger"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// ConversationController 对话控制器

type ConversationController struct {
	conversationService service.DeepSeekService
}

// NewConversationController 创建对话控制器实例
func NewConversationController(conversationService service.DeepSeekService) *ConversationController {
	return &ConversationController{
		conversationService: conversationService,
	}
}

// CreateConversationRequest 创建对话请求参数
type CreateConversationRequest struct {
	Title string `json:"title" binding:"required,min=1,max=255"`
}

// UpdateConversationRequest 更新对话请求参数
type UpdateConversationRequest struct {
	Title    string `json:"title" binding:"omitempty,min=1,max=255"`
	IsActive bool   `json:"is_active"`
}

// SendMessageRequest 发送消息请求参数
type SendMessageRequest struct {
	Content string `json:"content" binding:"required,min=1"`
}

// ChatWithDeepSeekRequest 与DeepSeek对话请求参数
type ChatWithDeepSeekRequest struct {
	Content   string                   `json:"content" binding:"required,min=1"`
	Functions []model.FunctionDefinition `json:"functions,omitempty"`
}

// CreateConversation 创建新对话
// @Summary 创建新对话
// @Description 创建新的对话
// @Tags 对话
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body CreateConversationRequest true "创建对话请求参数"
// @Success 200 {object} Response{data=model.Conversation}
// @Router /api/v1/conversations [post]
func (c *ConversationController) CreateConversation(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	uidInt64, ok := userID.(int64)
	if !ok {
		logger.Error("User ID type conversion error")
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "用户信息错误"))
		return
		}
	uid := uint(uidInt64)
	if !exists {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "未登录"))
		return
	}

	var req CreateConversationRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Error("Create conversation request binding error", zap.Error(err))
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, err.Error()))
		return
	}

	conversation, err := c.conversationService.CreateConversation(ctx, uid, req.Title)
	if err != nil {
		logger.Error("Create conversation error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	ctx.JSON(http.StatusOK, NewSuccessResponse(conversation, "创建成功"))
}

// GetUserConversations 获取用户对话列表
// @Summary 获取用户对话列表
// @Description 获取当前登录用户的对话列表
// @Tags 对话
// @Accept json
// @Produce json
// @Security Bearer
// @Param page query int false "页码，默认1"
// @Param page_size query int false "每页数量，默认10，最大100"
// @Success 200 {object} Response{data=map[string]interface{}}
// @Router /api/v1/conversations [get]
func (c *ConversationController) GetUserConversations(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "未登录"))
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "无效的用户ID"))
		return
	}

	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))

	// 限制每页数量
	if pageSize > 100 {
		pageSize = 100
	}
	if page < 1 {
		page = 1
	}

	conversations, total, err := c.conversationService.GetUserConversations(ctx, uid, page, pageSize)
	if err != nil {
		logger.Error("Get user conversations error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	response := map[string]interface{}{
		"list":      conversations,
		"total":     total,
		"page":      page,
		"page_size": pageSize,
	}

	ctx.JSON(http.StatusOK, NewSuccessResponse(response, "获取成功"))
}

// GetConversation 获取对话详情
// @Summary 获取对话详情
// @Description 获取指定对话的详细信息
// @Tags 对话
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "对话ID"
// @Success 200 {object} Response{data=model.Conversation}
// @Router /api/v1/conversations/{id} [get]
func (c *ConversationController) GetConversation(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "未登录"))
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "无效的用户ID"))
		return
	}

	// 获取对话ID
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, "无效的对话ID"))
		return
	}

	// 获取对话详情
	conversation, err := c.conversationService.GetConversation(ctx, uint(id))
	if err != nil {
		logger.Error("Get conversation error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	// 检查用户是否有权限访问该对话
	if conversation == nil || conversation.UserID != uid {
		ctx.JSON(http.StatusNotFound, NewErrorResponse(http.StatusNotFound, "对话不存在或无权访问"))
		return
	}

	ctx.JSON(http.StatusOK, NewSuccessResponse(conversation, "获取成功"))
}

// UpdateConversation 更新对话
// @Summary 更新对话
// @Description 更新对话信息
// @Tags 对话
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "对话ID"
// @Param request body UpdateConversationRequest true "更新对话请求参数"
// @Success 200 {object} Response{data=model.Conversation}
// @Router /api/v1/conversations/{id} [put]
func (c *ConversationController) UpdateConversation(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "未登录"))
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "无效的用户ID"))
		return
	}

	// 获取对话ID
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, "无效的对话ID"))
		return
	}

	// 获取对话详情
	conversation, err := c.conversationService.GetConversation(ctx, uint(id))
	if err != nil {
		logger.Error("Get conversation error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	// 检查用户是否有权限访问该对话
	if conversation == nil || conversation.UserID != uid {
		ctx.JSON(http.StatusNotFound, NewErrorResponse(http.StatusNotFound, "对话不存在或无权访问"))
		return
	}

	// 绑定请求参数
	var req UpdateConversationRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Error("Update conversation request binding error", zap.Error(err))
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, err.Error()))
		return
	}

	// 更新对话信息
	if req.Title != "" {
		conversation.Title = req.Title
	}
	conversation.IsActive = req.IsActive

	// 保存更新
	if err := c.conversationService.UpdateConversation(ctx, conversation); err != nil {
		logger.Error("Update conversation error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	ctx.JSON(http.StatusOK, NewSuccessResponse(conversation, "更新成功"))
}

// DeleteConversation 删除对话
// @Summary 删除对话
// @Description 删除指定的对话及其所有消息
// @Tags 对话
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "对话ID"
// @Success 200 {object} Response
// @Router /api/v1/conversations/{id} [delete]
func (c *ConversationController) DeleteConversation(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "未登录"))
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "无效的用户ID"))
		return
	}

	// 获取对话ID
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, "无效的对话ID"))
		return
	}

	// 获取对话详情
	conversation, err := c.conversationService.GetConversation(ctx, uint(id))
	if err != nil {
		logger.Error("Get conversation error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	// 检查用户是否有权限访问该对话
	if conversation == nil || conversation.UserID != uid {
		ctx.JSON(http.StatusNotFound, NewErrorResponse(http.StatusNotFound, "对话不存在或无权访问"))
		return
	}

	// 删除对话
	if err := c.conversationService.DeleteConversation(ctx, uint(id)); err != nil {
		logger.Error("Delete conversation error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	ctx.JSON(http.StatusOK, NewSuccessResponse(nil, "删除成功"))
}

// GetConversationMessages 获取对话消息
// @Summary 获取对话消息
// @Description 获取指定对话的消息列表
// @Tags 对话
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "对话ID"
// @Param page query int false "页码，默认1"
// @Param page_size query int false "每页数量，默认20，最大100"
// @Success 200 {object} Response{data=[]model.Message}
// @Router /api/v1/conversations/{id}/messages [get]
func (c *ConversationController) GetConversationMessages(ctx *gin.Context) {
	// 从上下文中获取用户ID
	_, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "未登录"))
		return
	}

	// 获取对话ID
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, "无效的对话ID"))
		return
	}

	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "20"))

	// 限制每页数量
	if pageSize > 100 {
		pageSize = 100
	}
	if page < 1 {
		page = 1
	}

	// 获取对话消息
	messages, err := c.conversationService.GetConversationMessages(ctx, uint(id), page, pageSize)
	if err != nil {
		logger.Error("Get conversation messages error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	ctx.JSON(http.StatusOK, NewSuccessResponse(messages, "获取成功"))
}

// SendMessage 发送消息
// @Summary 发送消息
// @Description 向指定对话发送消息
// @Tags 对话
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "对话ID"
// @Param request body SendMessageRequest true "发送消息请求参数"
// @Success 200 {object} Response{data=model.Message}
// @Router /api/v1/conversations/{id}/messages [post]
func (c *ConversationController) SendMessage(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "未登录"))
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "无效的用户ID"))
		return
	}

	// 获取对话ID
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, "无效的对话ID"))
		return
	}

	// 绑定请求参数
	var req SendMessageRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Error("Send message request binding error", zap.Error(err))
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, err.Error()))
		return
	}

	// 发送消息
	message, err := c.conversationService.SendMessage(ctx, uint(id), uid, req.Content)
	if err != nil {
		logger.Error("Send message error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	ctx.JSON(http.StatusOK, NewSuccessResponse(message, "发送成功"))
}

// ChatWithDeepSeek 与DeepSeek对话
// @Summary 与DeepSeek对话
// @Description 与DeepSeek模型进行对话，支持Function Call
// @Tags 对话
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "对话ID"
// @Param request body ChatWithDeepSeekRequest true "与DeepSeek对话请求参数"
// @Success 200 {object} Response{data=map[string]interface{}}
// @Router /api/v1/conversations/{id}/deepseek [post]
func (c *ConversationController) ChatWithDeepSeek(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "未登录"))
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, NewErrorResponse(http.StatusUnauthorized, "无效的用户ID"))
		return
	}

	// 获取对话ID
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, "无效的对话ID"))
		return
	}

	// 绑定请求参数
	var req ChatWithDeepSeekRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Error("Chat with deepseek request binding error", zap.Error(err))
		ctx.JSON(http.StatusBadRequest, NewErrorResponse(http.StatusBadRequest, err.Error()))
		return
	}

	// 与DeepSeek对话
	userMessage, functionCall, err := c.conversationService.ChatWithDeepSeek(ctx, uint(id), uid, req.Content, req.Functions)
	if err != nil {
		logger.Error("Chat with deepseek error", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, NewErrorResponse(http.StatusInternalServerError, err.Error()))
		return
	}

	response := map[string]interface{}{
		"user_message": userMessage,
	}

	// 如果需要调用函数，返回函数调用信息
	if functionCall != nil {
		response["function_call"] = functionCall
	}

	ctx.JSON(http.StatusOK, NewSuccessResponse(response, "对话成功"))
}